﻿// <copyright file="CategoryDataService.cs" company="Auros Ltd.">
//     Copyright (c) Auros Ltd. All rights reserved.
// </copyright>

namespace Auros.Categorisation
{
    using System.Linq;
    using System.ServiceModel.Activation;
    using System.ServiceModel.Web;
    using Auros.Categorisation.Data;
    using Auros.Categorisation.Models;
    using System.Collections.Generic;

    /// <summary>
    /// Class defining the web service for accessing and managing category data.
    /// </summary>
    [System.ServiceModel.ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class CategoryDataService
    {
        /// <summary>
        /// Updates the category sort order.
        /// </summary>
        /// <param name="parentId">The parent id.</param>
        /// <param name="sortOrder">The CSV string of category IDs in the required sort order.</param>
        /// <returns>String response if the action was performed successfully.</returns>
        [System.ServiceModel.OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = "/UpdateSortOrder", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
        public string UpdateSortOrder(int parentId, string sortOrder)
        {
            int[] sortedIds = StringHelpers.StringToIntList(sortOrder).ToArray();

            CategoryRepository categoryRepository = new CategoryRepository();

            for (int i = 0; i < sortedIds.Length; i++)
            {
                Category category = categoryRepository.GetCategory(sortedIds[i]);
                category.SortOrder = i;
                category.Save();
            }

            return "Successfully Updated";

            // TODO: Implement success/fail.
        }

        /// <summary>
        /// Gets the single category.
        /// </summary>
        /// <param name="id">The ID of the category to find.</param>
        /// <returns>Category with the specified ID.</returns>
        [System.ServiceModel.OperationContract]
        [WebGet(UriTemplate = "/GetCategory?id={id}", ResponseFormat = WebMessageFormat.Json)]
        public CategoryServiceModel GetSingleCategory(int id)
        {
            var category = new CategoryRepository().GetCategory(id);

            return new CategoryServiceModel(category);
        }

        /// <summary>
        /// Gets the categories.
        /// </summary>
        /// <returns>Collection of categories.</returns>
        [System.ServiceModel.OperationContract]
        [WebGet(UriTemplate = "/GetCategories", ResponseFormat = WebMessageFormat.Json)]
        public CategoryServiceModel[] GetCategories()
        {
            return this.ToServiceModelArray(new CategoryRepository().GetCategories().Where(c => c.Enabled)).ToArray();
        }

        /// <summary>
        /// Gets the categories with parent.
        /// </summary>
        /// <param name="parentId">The parent id.</param>
        /// <returns>Collection of categories under the specified parent ID.</returns>
        [System.ServiceModel.OperationContract]
        [WebGet(UriTemplate = "/GetCategories?parentId={parentId}", ResponseFormat = WebMessageFormat.Json)]
        public CategoryServiceModel[] GetCategoriesWithParent(int parentId)
        {
            return this.ToServiceModelArray(new CategoryRepository().GetCategories(parentId).Where(c => c.Enabled)).ToArray();
        }

        /// <summary>
        /// Gets all categories.
        /// </summary>
        /// <returns>Collection of categories.</returns>
        [System.ServiceModel.OperationContract]
        [WebGet(UriTemplate = "/GetAllCategories", ResponseFormat = WebMessageFormat.Json)]
        public CategoryServiceModel[] GetAllCategories()
        {
            return this.ToServiceModelArray(new CategoryRepository().GetCategories()).ToArray();
        }

        /// <summary>
        /// Gets all categories with parent.
        /// </summary>
        /// <param name="parentId">The parent id.</param>
        /// <returns>Collection of categories under the specified parent ID.</returns>
        [System.ServiceModel.OperationContract]
        [WebGet(UriTemplate = "/GetAllCategories?parentId={parentId}", ResponseFormat = WebMessageFormat.Json)]
        public CategoryServiceModel[] GetAllCategoriesWithParent(int parentId)
        {
            return this.ToServiceModelArray(new CategoryRepository().GetCategories(parentId)).ToArray();
        }

        /// <summary>
        /// Converts a collection category items to the model for returning from the service.
        /// </summary>
        /// <param name="enumerable"></param>
        /// <returns></returns>
        private IEnumerable<CategoryServiceModel> ToServiceModelArray(IEnumerable<Category> enumerable)
        {
            foreach (var item in enumerable)
            {
                yield return new CategoryServiceModel(item);
            }
        }
    }
}